package com.cqhfan.imservice.interceptors;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.cqhfan.core.constans.BizConstants;
import com.cqhfan.core.domain.dto.UserAuthDTO;
import com.cqhfan.core.utils.JwtUtil;
import com.cqhfan.redis.constants.RedisConstants;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import java.util.Map;

/**
 * @author 眭传洪
 * @create 2025-08-16 1:52
 */
@Slf4j
@Component
public class CustomHandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Value("${douyin.jwt.public-key}")
    private String publicKey;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 从 URL 路径中提取 token解析登录用户
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            // 获取请求路径
            String path = servletRequest.getServletRequest().getRequestURI();
            String[] pathParts = path.split("/");

            // 检查路径是否符合预期格式
            if (pathParts.length < 4) {
                log.error("WebSocket连接路径格式错误: {}", path);
                return false;
            }

            // 截取token
            String token = pathParts[pathParts.length - 1];
            if (StrUtil.isBlank(token)) {
                log.error("WebSocket连接参数格式错误: {}", path);
                return false;
            }

            // 解析token
            Claims claims = JwtUtil.parseToken(token, publicKey);
            if (claims == null) {
                return false;
            }
            Object uuidObj = claims.get(BizConstants.TOKEN_LOGIN_INFO);
            String key = RedisConstants.LOGIN_CACHE_KEY_PREFIX + uuidObj.toString();
            String loginUserStr = stringRedisTemplate.opsForValue().get(key);
            UserAuthDTO userAuthInfo = JSONUtil.toBean(loginUserStr, UserAuthDTO.class);

            // 将 userId 和 type 存入 WebSocketSession 的属性中
            attributes.put(BizConstants.WEBSOCKET_CONNECTION_USER, userAuthInfo.getUserId());
        }
        // 调用父类的 beforeHandshake 方法，继续处理 HTTP 会话
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Exception ex) {
        // 握手完成后执行
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
